package com.dtp.core.spring;

import com.dtp.common.ApplicationContextHolder;
import com.dtp.common.constant.DynamicTpConst;
import com.dtp.common.properties.DtpProperties;
import com.dtp.common.timer.HashedWheelTimer;
import com.dtp.core.DtpRegistry;
import com.dtp.core.monitor.DtpEndpoint;
import com.dtp.core.monitor.DtpMonitor;
import com.dtp.core.support.DtpBannerPrinter;
import com.dtp.core.thread.NamedThreadFactory;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.boot.actuate.autoconfigure.endpoint.condition.ConditionalOnAvailableEndpoint;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.DependsOn;
import org.springframework.context.annotation.Role;

import java.util.concurrent.TimeUnit;

/**
 * 动态线程池基本bean配置
 *
 * @Role：bean角色定义为ROLE_APPLICATION(默认值)、ROLE_SUPPORT(辅助角色)、ROLE_INFRASTRUCTURE(后台角色，用户无感)，通常第一种就是
 * 表示应用程序或业务Bean，第三种表示框架内部的角色，第二种比较罕见，它们主要是用于逻辑区分，没有决定性的含义。
 *
 * @DependsOn：用来表示一个beanA的实例化依赖另一个beanB的实例化，但是A并不需要持有一个B的对象，如果需要的话就不用depends-on，直接用依赖注入
 * 就可以了或者ref标签。
 *
 * @author yanhom
 * @since 1.0.0
 *
 * @remark muse
 **/
@Configuration(proxyBeanMethods = false)
@EnableConfigurationProperties(DtpProperties.class)
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
public class DtpBaseBeanConfiguration {

    // dtp的后置处理器（负责将代码定义的线程池注册到DtpRegistry中）
    @Bean
    @DependsOn({"dtpApplicationContextHolder"})
    public DtpPostProcessor dtpPostProcessor() {return new DtpPostProcessor();}

    // dtp的应用上下文（获得指定的bean，bean与name的映射，ApplicationContext，Environment，并且支持事件发布）
    @Bean
    @Role(BeanDefinition.ROLE_INFRASTRUCTURE)
    public ApplicationContextHolder dtpApplicationContextHolder() {return new ApplicationContextHolder();}

    // dtp的注册器（负责注册线程池）
    @Bean
    public DtpRegistry dtpRegistry() {return new DtpRegistry();}

    // dtp的监控器（负责监控当前线程池，检查报警、收集监控指标）
    @Bean
    public DtpMonitor dtpMonitor() {return new DtpMonitor();}

    // dtp的端点（spring-boot-actuator向外暴露指标的端点配置）
    @Bean
    @ConditionalOnAvailableEndpoint
    public DtpEndpoint dtpEndpoint() {return new DtpEndpoint();}

    // dtp的横幅打印（打印"dynamic-tp"的logo）*/
    @Bean
    @ConditionalOnProperty(name = DynamicTpConst.BANNER_ENABLED_PROP, matchIfMissing = true, havingValue = "true")
    public DtpBannerPrinter dtpBannerPrinter() {return new DtpBannerPrinter();}

    // hash时间轮（用于实现任务超时监控、队列超时监控功能）
    @Bean
    public HashedWheelTimer hashedWheelTimer() {
        return new HashedWheelTimer(new NamedThreadFactory("dtpRunnable-timeout", true), 10, TimeUnit.MILLISECONDS);
    }

}
